<html>
    <head>
        <title>高级主题</title>
    </head>
    <body>
        <script>
             /*
                    五、高级主题

                            1、功能值提供程序  Feature Value Providers

                                    功能系统是可扩展的，任何派生自 FeatureValueProvider （或实现 IFeatureValueProvider）的类都可以为功能系统做出贡献，

                                    值提供程序负责"获取给定功能的当前值"。


                                    功能值提供程序"一个接一个地执行"。如果其中一个返回非空值，则使用该功能值，不执行其他提供程序。

                                    有三个预定义的值提供程序，按给定顺序执行：
                                                                            
                                        ①、TenantFeatureValueProvider：  尝试获取是否为当前租户显示设置了功能值。

                                        ②、EditionFeatureValueProvider：  获取当前版本的功能值。  
                                        
                                                    Edition Id是从当前主体标识（ICurrentPrincipalAccessor）中获取的，声明名称为editionid（定义为AbpClaimTypes.EditionId的常量）。
                                                    
                                                    版本不会为租户管理模块实现。你可以自己实现，也可以考虑使用ABP商业的SaaS模块。

                                        ③、DefaultValueFeatureValueProvider获取功能的默认值。


                                    你可以通过继承  FeatureValueProvider 来编写自己的提供程序。

                                    eg: 使用“SystemAdmin”作为“User_Type”声明值为用户启用所有功能:

                                                using System.Threading.Tasks;
                                                using Volo.Abp.Features;
                                                using Volo.Abp.Security.Claims;
                                                using Volo.Abp.Validation.StringValues;

                                                namespace FeaturesDemo
                                                {
                                                    public class SystemAdminFeatureValueProvider : FeatureValueProvider
                                                    {
                                                        public override string Name => "SA";

                                                        private readonly ICurrentPrincipalAccessor _currentPrincipalAccessor; // 当前主体访问器服务

                                                        public SystemAdminFeatureValueProvider(
                                                            IFeatureStore featureStore,
                                                            ICurrentPrincipalAccessor currentPrincipalAccessor)
                                                            : base(featureStore)
                                                        {
                                                            _currentPrincipalAccessor = currentPrincipalAccessor;  
                                                        }

                                                        public override Task<string> GetOrNullAsync(FeatureDefinition feature)
                                                        {
                                                            if (feature.ValueType is ToggleStringValueType &&
                                                                _currentPrincipalAccessor.Principal?.FindFirst("User_Type")?.Value == "SystemAdmin")
                                                            {
                                                                return Task.FromResult("true");
                                                            }

                                                            return null;
                                                        }
                                                    }
                                                }


                                        如果功能值提供程序返回null，则执行下一个提供程序。

                                        定义功能值提供程序后，应该将其添加到AbpFeatureOptions,如下所示：

                                                Configure<AbpFeatureOptions>(options =>
                                                {
                                                    options.ValueProviders.Add<SystemAdminFeatureValueProvider>();
                                                });

                                        在你的模块类的ConfigureServices中使用此代码。
                */
        </script>
    </body>
</html>